#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>

#define PORT 80
#define BUFFER_SIZE 1024
#define PAGE_PATH "index.html"

int main()
{
    int sockfd;
    struct sockaddr_in servaddr, cliaddr;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    memset(&cliaddr, 0, sizeof(cliaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);

    if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("Bind failed");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    if (listen(sockfd, 10) < 0)
    {
        perror("Listen failed");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", PORT);

    while (1)
    {
        socklen_t len = sizeof(cliaddr);
        int connfd = accept(sockfd, (struct sockaddr *)&cliaddr, &len);
        if (connfd < 0)
        {
            perror("Accept failed");
            continue;
        }

        char buffer[BUFFER_SIZE] = {0};
        read(connfd, buffer, sizeof(buffer));

        FILE *file = fopen(PAGE_PATH, "r");
        if (file == NULL)
        {
            char *response = "HTTP/1.1 404 Not Found\r\nContent - Type: text/html\r\n\r\n<html><body><h1>404 Not Found</h1></body></html>";
            write(connfd, response, strlen(response));
        }
        else
        {
            char *response_header = "HTTP/1.1 200 OK\r\nContent - Type: text/html\r\n\r\n";
            write(connfd, response_header, strlen(response_header));
            char file_buffer[BUFFER_SIZE];
            while (fgets(file_buffer, sizeof(file_buffer), file) != NULL)
            {
                write(connfd, file_buffer, strlen(file_buffer));
            }
            fclose(file);
        }

        close(connfd);
    }

    close(sockfd);
    return 0;
}